package com.muyun.data.modeler.infrastructure.handler;

import com.muyun.data.modeler.infrastructure.general.consts.MessageConsts;
import com.muyun.data.modeler.infrastructure.general.exceptions.TipException;
import com.muyun.data.modeler.infrastructure.general.specs.ApiResponse;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.crypto.IllegalBlockSizeException;
import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理
 * @author muyun12
 * @date 2020-12-22 21:44:51
 * @since 0.1.0
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    private MessageSourceAccessor messageSourceAccessor;

    @ResponseBody
    @ExceptionHandler(value = TipException.class)
    public ApiResponse tipException(TipException ex) {
        logger.info(ex.getMessage());
        return ApiResponse.fail(ex.getResult(), ex.getCode(), ex.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ApiResponse methodArgumentNotValidException(MethodArgumentNotValidException ex) {
        logger.error(messageSourceAccessor.getMessage(MessageConsts.CODE_1000), ex);
        return ApiResponse.fail(ex.getFieldError().getDefaultMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ApiResponse constraintViolationException(ConstraintViolationException ex) {
        logger.error(messageSourceAccessor.getMessage(MessageConsts.CODE_1000), ex);
        StringBuilder msg = new StringBuilder();
        ex.getConstraintViolations().forEach(c -> {
            msg.append(c.getMessage());
        });
        return ApiResponse.fail(msg.toString());
    }

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ApiResponse exception(Exception ex) {
        logger.error(messageSourceAccessor.getMessage(MessageConsts.CODE_9999), ex);
        String message = messageSourceAccessor.getMessage(MessageConsts.CODE_9999);
        if (ex instanceof IllegalBlockSizeException) {
            message = messageSourceAccessor.getMessage(MessageConsts.CODE_1002);
        }
        return ApiResponse.fail(message);
    }

    @Autowired
    public void setMessageSourceAccessor(MessageSourceAccessor messageSourceAccessor) {
        this.messageSourceAccessor = messageSourceAccessor;
    }
}
